#include "mb_cmc_dev.h"

/* cmc 设备私有数据 */
cmc_prvt s_cmc_prvt = 
{
    /* 历史选择记录全部初始化为 CMC_UNKNOWN */
    .sel_history = CMC_DEV_SELS_INIT_CFG,
};

/* cmc 设备操作对象结构体 */
cmc_op_t s_cmc_ops[CMC_SELECT_MAX_NBR];

#ifndef MB_DEV_DISABLE_INIT
/* cmc 设备初始化函数 (新的设备初始化函数, 添加到此处) */
cmc_init cmc_inits[CMC_SELECT_MAX_NBR] = 
{
    /* CMC_USART */
    NULL,
    /* CMC_NET */
    NULL,
    /* CMC_WIFI */
    NULL,
    /* CMC_LORA */
    NULL,
    /* CMC_4G */
    NULL
};
#endif

/* cmc 设备注册函数接口 (新的设备操作注册函数, 添加到此处)  */
cmc_op_register cmc_op_register_funcs[CMC_SELECT_MAX_NBR] = 
{
    /* CMC_USART */
    cmc_usart_op_register,

    /* CMC_NET */
    NULL,

    /* CMC_WIFI */
    NULL, 

    /* CMC_LORA */
    NULL,

    /* CMC_4G */
    NULL
};


/* -------------------------- cmc 设备初始化 -------------------------- */

/* 选择 cmc 设备 */
static int mb_cmc_dev_select(CMC_SELECT sel)
{
    int i;

    /* 判断是否已经选择过设备 */
    for (i = 0; i < sizeof(s_cmc_prvt.sel_history); i++)
    {
        
        if (s_cmc_prvt.sel_history[i] == sel)
        {
            return -1;  /* sel 在 当前系统中 已被选择(处于可用状态) */
        }
    }

    /* 是新的设备选择 */
    s_cmc_prvt.cursel =  sel;

    return 0;
}

/* 注册 cmc 硬件设备操作 */
static cmc_op_t mb_cmc_dev_op_register(void)
{
    /* 判断当前设备是否已被注册 */
    if (s_cmc_prvt.sel_history[s_cmc_prvt.cursel] != CMC_UNKNOWN)
    {
        return NULL;
    }

    /* 注册设备操作接口 */
    s_cmc_ops[s_cmc_prvt.cursel] = cmc_op_register_funcs[s_cmc_prvt.cursel]();

    /* 将该设备加进设备选择记录 */
    s_cmc_prvt.sel_history[s_cmc_prvt.cursel] = s_cmc_prvt.cursel;

    /* 返回这个设备的操作接口 */
    return s_cmc_ops[s_cmc_prvt.cursel];
}

/* ----------------------------- 注册指定的CMC设备操作函数接口 ----------------------------- */

/* 注册 cmc 设备操作 */
cmc_op_t mb_cmc_op_register(CMC_SELECT sel)
{
    int      ret;
    cmc_op_t sret;

    /* 判断参数有效性 */
    if (sel >= CMC_UNKNOWN)
    {
        return NULL;    /* 注册失败 */
    }

    /* 选择 cmc 设备 */
    ret = mb_cmc_dev_select(sel);

    if (ret != 0)
    {
        return NULL;    /* 硬件设备选择失败, 已被选择(处于可用状态) */
    }

    /* 注册 cmc 硬件设备操作 */
    sret = mb_cmc_dev_op_register();

    if (sret == NULL)
    {
        return NULL;    /* 设备未被选择, 但是硬件操作函数注册失败 */
    }

    /* 返回该 CMC 设备操作函数接口 */
    return sret;
}
